package com.tianji.promotion.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.promotion.constants.PromotionConstants;
import com.tianji.promotion.domain.po.Coupon;
import com.tianji.promotion.domain.po.ExchangeCode;
import com.tianji.promotion.mapper.ExchangeCodeMapper;
import com.tianji.promotion.service.IExchangeCodeService;
import com.tianji.promotion.utils.CodeUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 兑换码 服务实现类
 * </p>
 *
 * @author llt
 * @since 2024-08-06
 */
@Service
@RequiredArgsConstructor
public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, ExchangeCode> implements IExchangeCodeService {

    private final StringRedisTemplate redisTemplate;

    @Override
    @Async("generateExchangeCodeExecutor")
    public void ayncGenerateExchangeCode(Coupon coupon) {
        // 1. 生成自增 id
        Integer totalNum = coupon.getTotalNum(); // 要生成兑换码的数量
        Long increment = redisTemplate.opsForValue().increment(PromotionConstants.COUPON_CODE_SERIAL_KEY, totalNum);
        if (increment == null) {
            return;
        }

        // 2. 调用工具类生产兑换码
        int maxSerialNum = increment.intValue(); // 优惠卷生成后的总数量
        int begin = maxSerialNum - totalNum + 1; // 该开始生成第几张
        List<ExchangeCode> list = new ArrayList<>();
        for (int i = begin; i <= maxSerialNum; i++) {
            String code = CodeUtil.generateCode(i, coupon.getId());// 第一个参数是第几张优惠券, 第二个值是优惠券id（用来找秘钥）
            // 3. 将兑换码保存 db
            ExchangeCode exchangeCode = new ExchangeCode();
            exchangeCode.setId(i);
            exchangeCode.setCode(code);
            exchangeCode.setExchangeTargetId(coupon.getId());
            exchangeCode.setExpiredTime(coupon.getIssueEndTime());
            list.add(exchangeCode);
        }

        this.saveBatch(list);
    }

    // 修改兑换码自增 id 对应的 offect 值
    @Override
    public boolean updateExchangeCodeMark(long serialNum, boolean flag) {
        String key = PromotionConstants.COUPON_CODE_MAP_KEY;
        Boolean setBit = redisTemplate.opsForValue().setBit(key, serialNum, flag); // 返回的是之前的值
        return setBit != null && setBit;
    }
}
